/*
 * TStore
 * Petko D. Petkov; GNUCITIZEN; http://www.gnucitizen.org
 */

function TStore(store) {
	this.triples = [];

	if (store != undefined)
		this.inject(store);
}

TStore.prototype.insert = function (triple) {
	this.triples.push(triple);
};

TStore.prototype.remove = function (triple) {
	if (triple == undefined || (!triple.subject && !triple.predicate && !triple.object)) {
		this.triples = [];
		return;
	}

	var triples = [];

	for (var i = 0; i < this.triples.length; i++)
		if (!this.match(triple, this.triples[i]))
			triples.push(this.triples[i]);

	this.triples = triples;
};

TStore.prototype.update = function (search, triple) {
	for (var i = 0; i < this.triples.length; i++)
		if (this.match(search, this.triples[i])) {
			if (triple.subject)
				this.triples[i].subject = triple.subject;
				
			if (triple.predicate)
				this.triples[i].predicate = triple.predicate;
				
			if (triple.object)
				this.triples[i].object = triple.object;
		}
};

TStore.prototype.inject = function (store) {
	var triples = store.search();

	for (var i = 0; i < triples.length; i++)
		this.triples.push(triples[i]);
};

TStore.prototype.shrink = function () {
	var store = new TStore;

	for (var i = 0; i < this.triples.length; i++)
		if (!store.search(this.triples[i]).length)
			store.insert(this.triples[i]);

	this.triples = [];
	this.update(store);
};

TStore.prototype.search = function (triple) {
	if (triple == undefined || (!triple.subject && !triple.predicate && !triple.object))
		return this.triples;

	var triples = [];

	for (var i = 0; i < this.triples.length; i++)
		if (this.match(triple, this.triples[i]))
			triples.push(this.triples[i]);

	return triples;
};

TStore.prototype.find = function (triple) {
	for (var i = 0; i < this.triples.length; i++)
		if (this.match(triple, this.triples[i]))
			return this.triples[i];

	return {subject: null, predicate: null, object: null};
};

TStore.prototype.match = function (triple, match) {
	return (!triple.subject || triple.subject == match.subject) &&
	       (!triple.object || triple.object == match.object) &&
	       (!triple.predicate || triple.predicate == match.predicate);
};